# coding=utf-8
import logging

from django.conf import settings
from django.db.models.fields.reverse_related import OneToOneRel
from rest_framework import exceptions, status
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response

from social.account.models import User
from social.exceptions import APIException, LogoutException
from django.utils.translation import gettext_lazy as _

logger = logging.getLogger("errors")

# social.account.models.User.home_setting.RelatedObjectDoesNotExist
err = {getattr(User, i.name).RelatedObjectDoesNotExist: i.related_model for i in User._meta.related_objects if
       isinstance(i, OneToOneRel) and i.name != "profile"}


def http_exception_handler(exc, context):
    logger.debug(f"ERROR:{type(exc)}, {exc}, {context}")
    response = None
    if isinstance(exc, tuple(err.keys())):
        request = context['request']
        err.get(type(exc)).objects.create(user_id=request.user.id)
        response = Response(status=status.HTTP_400_BAD_REQUEST, data={
            'code': -1,
            'message': _("请稍后重试")
        })
    elif isinstance(exc, LogoutException):
        response = Response(status=401, data={'code': 9999, 'message': exc.detail})
    elif isinstance(exc, APIException):
        response = Response(status=status.HTTP_400_BAD_REQUEST, data={
            'code': exc.status_code,
            'message': exc.detail,
        })

    elif isinstance(exc, (exceptions.AuthenticationFailed,
                          exceptions.NotAuthenticated)):
        response = Response(status=401)

    elif isinstance(exc, ValidationError):
        # 框架自带检查报错
        detail = exc.detail
        value = list(detail.values())[0][0]
        response = Response(
            status=status.HTTP_400_BAD_REQUEST,
            data={
                "code": exc.status_code,
                "message": value,
                "extra": str(exc) if settings.DEBUG else None
            }
        )
    elif isinstance(exc, exceptions.APIException):
        if settings.DEBUG:
            if isinstance(exc.detail, (list, dict)):
                data = exc.detail
            else:
                data = {'detail': exc.detail}
        else:
            data = None
        response = Response(status=exc.status_code, data=data)  # exc.detail is dict

    if response:
        logger.debug(f"Response:{response.data}, {response.status_code}")
    return response
